package com.mcy.springbatch.job;

import com.mcy.springbatch.job.BaseJobConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * 决策器的使用，当执行多个step时，如果需要根据上个step执行状态，例如COMPLETED、FAILED等状态来判断是否执行下一个step时，
 * 可以使用from-on-to模式，这个模式默认是根据step的执行状态，成功与否来做判断标准，当需要自定义step执行的结果来判断，
 * 就可以使用决策器JobExecutionDecider来实现
 */
@Slf4j
@Configuration
public class DeciderJobConfig extends BaseJobConfig {

    @Autowired
    private MyDecider myDecider;
    @Bean
    public Job decideDemoJob(){
        return jobBuilderFactory.get("decideDemoJob")
                .incrementer(new RunIdIncrementer())
                .start(deciderDemoStep1())
                .next(myDecider)
                .from(myDecider).on("even").to(deciderDemoStep2())
                .from(myDecider).on("odd").to(deciderDemoStep3())
                .from(deciderDemoStep3()).on("*").to(myDecider)
                .end()
                .build();
    }

    @Bean
    public Step deciderDemoStep1() {
        return stepBuilderFactory.get("deciderDemoStep1")
                .tasklet((stepContribution, chunkContext) -> {
                    log.info("deciderDemoStep1...");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step deciderDemoStep2() {
        return stepBuilderFactory.get("deciderDemoStep2")
                .tasklet((stepContribution, chunkContext) -> {
                    log.info("deciderDemoStep2...");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

    @Bean
    public Step deciderDemoStep3() {
        return stepBuilderFactory.get("deciderDemoStep3")
                .tasklet((stepContribution, chunkContext) -> {
                    log.info("deciderDemoStep3...");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }



    @Component
    class MyDecider implements JobExecutionDecider{

        private int count;

        @Override
        public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
            count += 1;
            log.info("count:{}",count);
            if(count % 2 == 0){
                return new FlowExecutionStatus("even");
            }else {
                return new FlowExecutionStatus("odd");
            }
        }
    }


}
